#pragma once

#include <unistd.h>
#include <vector>

#include "reactor.hpp"
#include "listener.hpp"
#include "pipeconnetion.hpp"
#include "Slaver.hpp"

class Master{
public:
    Master(uint16_t port):_port(port)
    {
        _lisrensock=make_Listener(_port);
    }
    void MakeSlaver(){//运行之后，就不支持创建slaver了
        int pipes[2];
        pipe(pipes);//创建管道

        pid_t id=::fork();
        
        if(id==0){
            ::close(pipes[1]);
            slaver s;
            s.init();
            //1.将listensock加入到子进程中
            s.set_listensock(_lisrensock);
            //2.将管道读端添加到子进程中
            connect_t pipe=make_pipe(ReadEnd,pipes[0]);
            s.set_read_pipe(pipe);
            //3.运行子进程
            s.start();
            exit(0);
        }
        //父进程运行部分:将子进程的管道读端关闭，保留写端
        ::close(pipes[0]);
        connect_t w_pipe=make_pipe(WriteEnd,pipes[1]);
        slavers.push_back(w_pipe);
        _child_cnt++;
    }
    void setlistensock(connect_t listensock){_lisrensock=listensock;}
    void start(){
        _epoll.add(*_lisrensock);
        while(true){
            _epoll.wait(&listenevent,1,-1);
            if(listenevent.events&EPOLLIN==EPOLLIN){
                //让子进程调用accept
                static_cast<pipeconnection*>(slavers[i].get())->setcommand(ACCEPT);
                slavers[i++]->_send();//负载均衡
                i%=_child_cnt;
            }
        }
    }
private:
    std::vector<connect_t> slavers;//slaver的写端
    int _child_cnt=0;//子进程的数量
    uint16_t _port;
    connect_t _lisrensock;
    epoller _epoll;
    struct epoll_event listenevent;
    int i=0;
};